import redis
from typing import Dict, Any, Optional, Union, List, Tuple, Set

config = {
        'default': {
            'host': '124.220.33.71',
            'port': 6379,
            'db': 0,
            'max_connections': 50,
            'password': 'aojTG9LkVMBHNAeU',
        }
    }
class RedisPoolManager:
    """Redis连接池管理器，支持多数据源配置"""

    _pools = {}

    @classmethod
    def add_config(cls, alias: str, config: Dict[str, Any]) -> None:
        """添加Redis配置并创建连接池"""
        required_params = {'host', 'port'}
        missing_params = required_params - set(config.keys())
        if missing_params:
            raise ValueError(f"缺少必要的Redis配置参数: {', '.join(missing_params)}")

        pool_config = {
            'host': config['host'],
            'port': config['port'],
            'db': config.get('db', 0),
            'password': config.get('password'),
            'max_connections': config.get('max_connections', 10),
            'decode_responses': config.get('decode_responses', True),
            'socket_timeout': config.get('socket_timeout', 5),
            'socket_connect_timeout': config.get('socket_connect_timeout', 5),
        }

        cls._pools[alias] = redis.ConnectionPool(**pool_config)

    @classmethod
    def initialize(cls) -> None:
        """批量添加Redis配置"""
        RedisPoolManager.add_configs(config)

    @classmethod
    def add_configs(cls, configs: Dict[str, Dict[str, Any]]) -> None:
        """批量添加Redis配置"""
        for alias, config in configs.items():
            cls.add_config(alias, config)

    @classmethod
    def get(cls, alias: str) -> 'RedisClient':
        """获取指定配置的Redis客户端"""
        if alias not in cls._pools:
            raise ValueError(f"Redis配置别名 '{alias}' 不存在")
        return RedisClient(cls._pools[alias])

    @classmethod
    def close_all(cls) -> None:
        """关闭所有连接池"""
        for pool in cls._pools.values():
            pool.disconnect()
        cls._pools.clear()


class RedisClient:
    """Redis客户端，封装常用操作方法"""

    def __init__(self, pool: redis.ConnectionPool):
        self._pool = pool
        self._client = redis.Redis(connection_pool=pool)

    # ------------------- String 操作 -------------------
    def set(self, key: str, value: Any, ex: Optional[int] = None, px: Optional[int] = None, nx: bool = False,
            xx: bool = False) -> bool:
        """设置键值对"""
        return self._client.set(key, value, ex=ex, px=px, nx=nx, xx=xx)

    def get(self, key: str) -> Optional[str]:
        """获取键对应的值"""
        return self._client.get(key)

    def mset(self, mapping: Dict[str, Any]) -> bool:
        """批量设置键值对"""
        return self._client.mset(mapping)

    def mget(self, keys: List[str]) -> List[Optional[str]]:
        """批量获取键对应的值"""
        return self._client.mget(keys)

    def incr(self, key: str, amount: int = 1) -> int:
        """将键的值递增"""
        return self._client.incr(key, amount)

    def decr(self, key: str, amount: int = 1) -> int:
        """将键的值递减"""
        return self._client.decr(key, amount)

    # ------------------- Hash 操作 -------------------
    def hset(self, name: str, key: str, value: Any) -> int:
        """设置哈希表中的字段值"""
        return self._client.hset(name, key, value)

    def hget(self, name: str, key: str) -> Optional[str]:
        """获取哈希表中字段的值"""
        return self._client.hget(name, key)

    def hmset(self, name: str, mapping: Dict[str, Any]) -> bool:
        """批量设置哈希表中的字段值"""
        return self._client.hmset(name, mapping)

    def hmget(self, name: str, keys: List[str]) -> List[Optional[str]]:
        """批量获取哈希表中字段的值"""
        return self._client.hmget(name, keys)

    def hgetall(self, name: str) -> Dict[str, str]:
        """获取哈希表中所有字段和值"""
        return self._client.hgetall(name)

    def hdel(self, name: str, *keys: str) -> int:
        """删除哈希表中的一个或多个字段"""
        return self._client.hdel(name, *keys)

    # ------------------- List 操作 -------------------
    def lpush(self, name: str, *values: Any) -> int:
        """将一个或多个值插入到列表头部"""
        return self._client.lpush(name, *values)

    def rpush(self, name: str, *values: Any) -> int:
        """将一个或多个值插入到列表尾部"""
        return self._client.rpush(name, *values)

    def lpop(self, name: str) -> Optional[str]:
        """移除并获取列表的第一个元素"""
        return self._client.lpop(name)

    def rpop(self, name: str) -> Optional[str]:
        """移除并获取列表的最后一个元素"""
        return self._client.rpop(name)

    def lrange(self, name: str, start: int, end: int) -> List[str]:
        """获取列表指定范围内的元素"""
        return self._client.lrange(name, start, end)

    def llen(self, name: str) -> int:
        """获取列表的长度"""
        return self._client.llen(name)

    # ------------------- Set 操作 -------------------
    def sadd(self, name: str, *values: Any) -> int:
        """向集合添加一个或多个成员"""
        return self._client.sadd(name, *values)

    def srem(self, name: str, *values: Any) -> int:
        """移除集合中一个或多个成员"""
        return self._client.srem(name, *values)

    def smembers(self, name: str) -> Set[str]:
        """获取集合中的所有成员"""
        return self._client.smembers(name)

    def sismember(self, name: str, value: Any) -> bool:
        """判断成员是否是集合的成员"""
        return self._client.sismember(name, value)

    def scard(self, name: str) -> int:
        """获取集合的成员数"""
        return self._client.scard(name)

    # ------------------- Key 操作 -------------------
    def exists(self, *keys: str) -> int:
        """检查给定键是否存在"""
        return self._client.exists(*keys)

    def delete(self, *keys: str) -> int:
        """删除一个或多个键"""
        return self._client.delete(*keys)

    def expire(self, key: str, seconds: int) -> bool:
        """为键设置过期时间"""
        return self._client.expire(key, seconds)

    def ttl(self, key: str) -> int:
        """获取键的剩余过期时间"""
        return self._client.ttl(key)

    def keys(self, pattern: str) -> List[str]:
        """查找所有符合给定模式的键"""
        return self._client.keys(pattern)

    def close(self) -> None:
        """关闭客户端连接"""
        self._client.close()


# 示例用法
if __name__ == "__main__":


    # 获取指定配置的Redis客户端
    default_client = RedisPoolManager.get('default')
    cache_client = RedisPoolManager.get('cache')

    # 使用客户端操作Redis
    default_client.set('key1', 'value1')
    print(default_client.get('key1'))

    cache_client.set('key2', 'value2')
    print(cache_client.get('key2'))

    # 关闭客户端连接
    default_client.close()
    cache_client.close()

    # 关闭所有连接池
    RedisPoolManager.close_all()